package com.bxait.toymail.product.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.bxait.com.to.es.SkuEsModel;
import com.bxait.com.utils.PageUtils;
import com.bxait.com.utils.Query;
import com.bxait.com.utils.R;
import com.bxait.com.vo.product.Attr;
import com.bxait.com.vo.product.BrandVo;
import com.bxait.com.vo.product.CateLogVo;
import com.bxait.toymail.product.dao.SkuSaleAttrValueDao;
import com.bxait.toymail.product.entity.*;
import com.bxait.toymail.product.feign.SecKillFeignService;
import com.bxait.toymail.product.service.*;
import com.bxait.toymail.product.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.bxait.toymail.product.dao.SkuInfoDao;

import javax.annotation.Resource;
import javax.naming.directory.SearchResult;

@Slf4j
@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Resource
    ThreadPoolExecutor executor;
    @Resource
    AttrService attrService;


    @Resource
    @Qualifier("skuImagesService")
    SkuImagesService imagesService;
    @Resource
    @Qualifier("brandService")
    BrandService brandService;
    @Resource
    SkuSaleAttrValueDao skuSaleAttrValueDao;

    @Resource
    @Qualifier("skuSaleAttrValueService")
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Resource
    @Qualifier("spuInfoDescService")
    SpuInfoDescService spuInfoDescService;

    @Resource
    @Qualifier("attrGroupService")
    AttrGroupService attrGroupService;

    @Resource
    SecKillFeignService secKillFeignService;
    @Resource
    CategoryService categoryService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                new QueryWrapper<SkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * @param params
     * @==============History===============<br/>
     * @Description // TODO  获取sku列表
     * @Date 2023/3/21 19:57
     * @Author <a href="qq:2277411582@qq.com">chen</a>
     * @return com.bxait.com.utils.PageUtils
     */
    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        QueryWrapper<SkuInfoEntity>
                queryWrapper = new QueryWrapper<>();



        // id与name的查询条件
        String key = (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            queryWrapper.and((wrapper)->{
                wrapper.eq("sku_id",key).or().like("sku_name",key);
            });
        }
        // 品牌id的条件
        String brandId = (String) params.get("brandId");
        if(!StringUtils.isEmpty(brandId)){
            queryWrapper.eq("brand_id",brandId);
        }

        // 分类id的条件
        String catelogId = (String) params.get("catelogId");
        if(!StringUtils.isEmpty(catelogId)){
            queryWrapper.eq("catalog_id",catelogId);
        }

        // 最小价格的条件
        String min = (String) params.get("min");
        if(!StringUtils.isEmpty(min)){
            queryWrapper.ge("price",min);
        }

        String max = (String) params.get("max");
        if(!StringUtils.isEmpty(max)  ){
            try{
                BigDecimal bigDecimal = new BigDecimal(max);
                if(bigDecimal.compareTo(new BigDecimal("0"))==1){
                    queryWrapper.le("price",max);
                }
            }catch (Exception e){
            }
        }

        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    /*
     * @param spuId
     * @==============History===============<br/>
     * @Description // TODO  获取当前商品spu对应的sku信息
     * @Date 2023/4/13 22:22
     * @Author <a href="qq:2277411582@qq.com">chen</a>
     * @return java.util.List<com.bxait.toymail.product.entity.SkuInfoEntity>
     */
    @Override
    public List<SkuInfoEntity> getSkusBySpuId(Long spuId) {
        QueryWrapper<SkuInfoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("spu_id", spuId);
        List<SkuInfoEntity> list = this.list(wrapper);
        return list;
    }

    /*
     * @param skuId
     * @==============History===============<br/>
     * @Description //   获取当前商品详情信息
     * @Date 2023/4/17 2023/4/17 
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return [java.lang.Long]
     */
    @Override
    public SkuItemVo item(Long skuId) {

        SkuItemVo skuItemVo = new SkuItemVo();

        // 1.获取sku基本信息(获取到基本信息,需要返回这个基本信息,获取到的数据中的spu信息,是我们需要在下一步使用的)
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(()->{
            SkuInfoEntity infoEntity = this.getById(skuId);
            skuItemVo.setInfo(infoEntity);
             return infoEntity;
        },executor);

        // 4.获取当前spu的销售属性组合(我们获取到当前sku所属spu下的所有的sku信息,将这些sku的属性信息都收集起来在页面展示,然后把这个销售属性值在
        // 那些sku信息中有我们也收集起来,将来在页面上进行点击sku属性信息组合时,我们会跳转到具体的sku详情页)
        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            // 获取上一次结果中返回的商品spuId
            Long spuId = res.getSpuId();
            // 获取这个spu商品下的所有sku属性信息
            List<SkuItemSaleAttrVo> saleAttrVos =  skuSaleAttrValueService.getSaleAttrBySpuId(spuId);
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        // 5.获取当前spu的介绍信息
        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            Long spuId = res.getSpuId();
            SpuInfoDescEntity descEntity = spuInfoDescService.getById(spuId);
            skuItemVo.setDesc(descEntity);
        }, executor);

        // 6.获取spu的规格参数信息
        CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            Long spuId = res.getSpuId();
            Long catalogId = res.getCatalogId();
            List<SpuItemAttrGroupVo> groupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId, catalogId);
            skuItemVo.setGroupAttrs(groupVos);
        }, executor);

        // 2.获取sku的图片信息(该方法不需要返回值)
        CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
           List<SkuImagesEntity> imagesEntities = imagesService.getImagesBySkuId(skuId);
           skuItemVo.setImages(imagesEntities);
        }, executor);

        // 3.获取当前sku是否参与秒杀优惠
        CompletableFuture<Void> secKillFuture = CompletableFuture.runAsync(() -> {
            R secKillInfo = secKillFeignService.getSkuSecKillInfo(skuId);
            if (secKillInfo.getCode() == 0) {
                SecKillInfoVo secKillInfoVo = secKillInfo.getData(new TypeReference<SecKillInfoVo>() {});
                skuItemVo.setSeckillInfo(secKillInfoVo);
            }
        }, executor);


        // 7.等所有任务都完成
        try {
            CompletableFuture.allOf(saleAttrFuture,descFuture,baseAttrFuture,imageFuture,secKillFuture).get();
        } catch (Exception e) {
            e.printStackTrace();
            log.info("获取sku{}详情信息失败{}",skuId,e.getMessage());
        }

        return skuItemVo;

    }

    /*
     * @param
     * @==============History===============<br/>
     * @Description //   提供给检索服务的搜索方法
     * @Date 2023/5/14 2023/5/14
     * @Author < a href="2277411582@qq.com">chen</ a>
     * @return javax.naming.directory.SearchResult
     */
    @Override
    public SearchResultProduct search() {
        SearchResultProduct searchResultProduct = new SearchResultProduct();
        List<SearchResultProduct.NavVo> navs = new ArrayList<>();
        List<SkuInfoEntity> list = this.list(new QueryWrapper<SkuInfoEntity>().last("limit 0,5"));
        // 收集商品
        List<SkuEsModel> products = list.stream().map(item -> {
            SkuEsModel model = new SkuEsModel();
            model.setSkuId(item.getSkuId());
            model.setBrandId(item.getBrandId());
            model.setCatalogId(item.getCatalogId());
            model.setSpuId(item.getSpuId());
            model.setSkuTitle(item.getSkuTitle());
            model.setSkuPrice(item.getPrice());
            model.setSkuImg(item.getSkuDefaultImg());
            model.setSaleCount(item.getSaleCount());
            model.setHasStock(true);
            return model;
        }).collect(Collectors.toList());
        for (SkuEsModel product : products) {
            final Long brandId = product.getBrandId();
            BrandEntity brandEntity = brandService.getById(brandId);
            product.setBrandName(brandEntity.getName());
            CategoryEntity categoryEntity = categoryService.getById(product.getCatalogId());
            product.setCatalogName(categoryEntity.getName());
            List<AttrEntity> attrEntities = attrService.list();
            List<Attr> attrs = new ArrayList<>();
            for (AttrEntity attrEntity : attrEntities) {
                Attr attr = new Attr();
                attr.setAttrId(attrEntity.getAttrId());
                attr.setAttrName(attrEntity.getAttrName());
                attr.setAttrValue(attrEntity.getValueSelect());
                attrs.add(attr);
            }
            product.setAttrs(attrs);
        }
        searchResultProduct.setProducts(products);
        searchResultProduct.setPageNum(1);
        searchResultProduct.setTotal(999L);
        searchResultProduct.setTotalPages(50);
        List<BrandEntity> brandEntities = brandService.list(new QueryWrapper<BrandEntity>().last("limit 0,5"));
        List<BrandVo> brandVos = new ArrayList<>();
        for (BrandEntity brandEntity : brandEntities) {
            BrandVo vo = new BrandVo();
            vo.setBrandId(brandEntity.getBrandId());
            vo.setBrandImg(brandEntity.getLogo());
            vo.setBrandName(brandEntity.getName());
            brandVos.add(vo);
        }
        searchResultProduct.setBrands(brandVos);
        List<CategoryEntity> categoryEntities = categoryService.list(new QueryWrapper<CategoryEntity>().last("limit 0,5"));
        List<CateLogVo> cateLogVos = new ArrayList<>();
        for (CategoryEntity categoryEntity : categoryEntities) {
            CateLogVo cateLogVo = new CateLogVo();
            cateLogVo.setCateLogId(categoryEntity.getCatId());
            cateLogVo.setCateLogName(categoryEntity.getName());
            cateLogVo.setBrandName(categoryEntity.getName());
            cateLogVos.add(cateLogVo);
        }
        searchResultProduct.setCatalogs(cateLogVos);
        searchResultProduct.setNavs(navs);

        return searchResultProduct;
    }

    @Override
    public List<String> getSkuSaleAttrValues(Long skuId) {
        return skuSaleAttrValueDao.getSkuSaleAttrValuesAsStringList(skuId);
    }

    @Override
    public SkuInfoEntity info(Long skuId) {
        SkuInfoEntity infoEntity = this.getById(skuId);
        List<String> skuSaleAttrValuesAsStringList = skuSaleAttrValueDao.getSkuSaleAttrValuesAsStringList(skuId);
        infoEntity.setList(skuSaleAttrValuesAsStringList);
        return infoEntity;
    }

}